home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 06 - 1990 / 06.11 Nov 90 / NeuralNet Estimator⁄EDIT / Search methods.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-08-03  |  6.3 KB  |  215 lines  |  [TEXT/KAHL]

  1. #include "Neural Network.h"
  2. #include <math.h>
  3.  
  4. extern FILE *         Jac;
  5.  
  6. extern NeuralNet *    theNet;
  7. extern DTypeVector     yData;
  8. extern DTypeMatrix    XData;
  9. extern DTypeVector     Alpha[];
  10. extern DTypeVector    Pi;
  11. extern DTypeVector    Diag;
  12. extern DTypeVector    gradSS;
  13.  
  14. static unsigned int    totparms;    /* total parms in model, set by AllotSearchWorkSpace() */
  15. static int itncount = 0;
  16. static double baseSS;
  17. static double patSS;
  18. static double RelStep;
  19. static DTypeVector * base;
  20. static DTypeVector * base_;
  21.  
  22. /*----------------------
  23.     Hooke and Jeeve's method for direct search to find least squares, see
  24.     "Methods of Optimization" by G.R. Walsh.
  25.         Expects:
  26.         1. tolerance value steptol; stored in NeuralNet structure.
  27.         2. validly defined and alloted NeuralNet structure.
  28.         3. input data in matrix XData and output data values in vector yData.
  29.         4. total number of parameters for model in "totparms".
  30.     Returns termcode = FAIL if current parm value is not an approximate critical point 
  31.                      = METSTEPTOL if scaled step is less than steptol
  32.                      = EXCEEDITNLIM if iteratation limit exceeded
  33. */
  34. do_HookeJeeves()
  35. {
  36.     int termcode = 0;
  37.     int success;
  38.     
  39.     base = Π
  40.     base_ = &gradSS;
  41.     RelStep = 1.0;
  42.     SaveParms(&gradSS);                /* save current weight values in vector Pi */
  43.     
  44. printf("Starting Hooke and Jeeves method\n");    
  45.     while(termcode == 0)
  46.     {    patSS = Compute_SS();
  47.         success = ExMove();
  48.         switch(success)
  49.         {    case TRUE:            /* accept new base point, stored in W[] of net */
  50.             {
  51.                 PatMove();    /* exits on failure to find new base point */
  52.                 break;
  53.             }
  54.             case FALSE:            /* ExMove failed, so reduce step size and continue */
  55.             {
  56.                 RelStep = .5*RelStep;
  57.                 if (RelStep < theNet->steptol)
  58.                     termcode = METSTEPTOL;
  59.                 else if (itncount > theNet->itnlimit)
  60.                     termcode = EXCEDITNLIM;                    
  61.                 break;
  62.             }
  63.         } /* end of "switch(success)" */
  64.     } /* end of "while(termcode == 0)" */
  65.     
  66.     return(termcode);
  67. }
  68.  
  69. /*-----------------------
  70.     Pattern move where previous successful steps given in Diag and current weights given
  71.     in Pi.
  72. */
  73. PatMove()
  74. {
  75.     int j,k,N;
  76.     int flag = 0;
  77.     double ss;
  78.     DTypeVector * temp;
  79.     DataType * w;    /* pointer to weight matrix */
  80.     DataType * b;    /* pointer to previous base point, use Pi vector */
  81.     DataType * b_;    /* pointer to current base point, use gradSS vector */
  82.     
  83.     SaveParms(base);    /* save weights as base in case need to abandon new pattern */
  84.     baseSS = patSS;    /* save SS for comparison to patSS after pattern search */
  85.  
  86.     do
  87.     {            
  88.     /*---- install new pattern step and update patSS ----*/
  89.         b_ = *base_->cells;
  90.         for(j=0; j<theNet->OutLayer; j++)
  91.         {    N = (theNet->W[j].rows)*(theNet->W[j].cols);
  92.             w = *theNet->W[j].cells;
  93.             for(k=0; k<N; k++, w++, b_++)
  94.                 *w = 2*(*w) - *b_;            /* weights are still at base values here */
  95.         }
  96.         patSS = Compute_SS();    /* get new reference SS for exploratory move */
  97.  
  98.     /*---- try an exploratory step from new pattern ----*/
  99.         ExMove();            /* don't need success flag from ExMove() 
  100.                                     leaves best SS value in patSS*/
  101.  
  102.     /*---- check if explore step found better point ----*/
  103.     /*---- regardless of succ of failure of pattern step, set "base_" to "base"
  104.             and prepare to find a new base, either by another pattern move if previous
  105.             pattern move was successful, or another exploratory move if previous pattern
  106.             move unsuccessful*/
  107.         if(patSS<baseSS)        /* T => successful pattern step so prepare to make one more */
  108.         {    temp = base_;        
  109.             base_ = base;        /* this accepts new base, makes it the old base */
  110.             base = temp;
  111.             SaveParms(base);/* save weights as new base */
  112.             baseSS = patSS;        /* reset the base SS value */
  113.         }
  114.         else    /* F => unsuccessful pattern step so prepare for next explore move */
  115.         {    RestoreParms(base);    /* abandon new weights, go back to base */
  116.             temp = base_;        
  117.             base_ = base;        /* this accepts new base, makes it the old base */
  118.             base = temp;
  119.             flag = 1;                /* set flag to exit pattern move */
  120.         }
  121.         
  122.     } while(flag < 1);
  123. printf("patSS = %lf \n",patSS);
  124. }
  125.  
  126. /*----------------------
  127.     Do the exploratory moves.  
  128.     Resets patSS to minimum SS value found in exploratory search.
  129.     Returns success = TRUE if found SS reducing change 
  130.                     = FALSE if could not find SS reducing change
  131. */
  132. ExMove()
  133. {
  134.     int i,j,N;
  135.     int success;
  136.     double ss;            /* value of SS for an exploratory move */
  137.     double ss_;            /* minimum value of SS found in this execution of ExMove() */
  138.     DataType step;
  139.     DataType * w;
  140.     
  141.         itncount +=1;
  142.         
  143.         ss_ = patSS;
  144.         for(j=0; j<theNet->OutLayer; j++)
  145.         {    N = (theNet->W[j].rows)*(theNet->W[j].cols);
  146.             w = *theNet->W[j].cells;
  147.             for(i=0; i<N; i++, w++)
  148.             {    step = RelStep*(fabs(*w) + theNet->maxstep);
  149.                 *w = *w + step;
  150.                 ss = Compute_SS();
  151.                 if(ss<ss_)
  152.                     ss_ = ss;                /* save new SS and go to next explore step */
  153.                 else
  154.                 {    *w = *w - 2.0*step;
  155.                     ss = Compute_SS();
  156.                     if(ss<ss_)
  157.                         ss_ = ss;            /* save new SS and go to next explore step */
  158.                     else
  159.                     {    *w = *w + step;        /* restore old parm value since no SS reduction */
  160.                     }
  161.                 }
  162.             } /* end of for(i=0; k<N; i++, w++) */
  163.         } /* end of for(j=0; j<theNet->OutLayer; j++) */
  164.     success = ( ss_ < patSS ) ? TRUE : FALSE;
  165.     patSS = ss_;
  166.     return(success);
  167. }
  168.  
  169. /*----------------------
  170.     Allot memory for Alpha, Pi, and Diag data structures.
  171.     Requires # observations from the data structure.
  172.     Since is always run before execution of method, sets totparms variable.
  173. */
  174. AllotSearchWorkSpace()
  175. {
  176.     int i;
  177.     int mxprms = 1;        /* keep track of layer with largest number of parameters */
  178.  
  179.     totparms = 0;        
  180.         
  181.     for(i=0; i<theNet->OutLayer; i++)
  182.     {    totparms += (theNet->W[i].rows)*(theNet->W[i].cols);
  183.         AllotDTypeVector(&Alpha[i], theNet->Units[i]);
  184.                     /* values for Unit[i] in each layer must be set prior
  185.                         to execution of this step.  Also note that
  186.                         the Alpha[0] vector is not used, instead a pseudo vector is
  187.                         created from a row of the XData matrix.  Thus, the allocation
  188.                         for i=0 wastes (Alpha[0].row)*sizeof(DataType) bytes.
  189.                     */
  190.         if(Alpha[i].rows > mxprms) mxprms =  Alpha[i].rows;
  191.     }
  192.     AllotDTypeVector(&(Alpha[theNet->OutLayer]), 1);
  193.             /* this allots space for output layer, a scaler but aesthetically pleasing */
  194.  
  195.     AllotDTypeVector(&Pi,totparms);
  196.     AllotDTypeVector(&Diag,totparms);
  197.     AllotDTypeVector(&gradSS,totparms);
  198. }
  199.  
  200. LockSearchWorkSpace()
  201. {
  202.     HLock(Pi.cells);
  203.     HLock(Diag.cells);
  204.     HLock(gradSS.cells);
  205.     HLockNet();
  206. }
  207.  
  208. UnlockSearchWorkSpace()
  209. {
  210.     HUnlock(Pi.cells);
  211.     HUnlock(Diag.cells);
  212.     HUnlock(gradSS.cells);
  213.     HUnlockNet();
  214. }
  215.